home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
news
/
inn1.000
/
inn1.4sec-linux-src.tar
/
inn
/
frontends
/
ctlinnd.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-29
|
8KB
|
316 lines
/* $Revision: 1.24 $
**
** Send control messages to the InterNetNews daemon.
*/
#include "configdata.h"
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "libinn.h"
#include "clibrary.h"
#include "inndcomm.h"
#include "paths.h"
#include "macros.h"
/*
** Datatype for an entry in the command table.
*/
typedef struct _COMMAND {
STRING Command;
STRING Text;
int argc;
char Letter;
BOOL Glue;
} COMMAND;
STATIC COMMAND Commands[] = {
{ "addhist", "id arr exp post path...\tAdd history line",
5, SC_ADDHIST, TRUE },
{ "allow", "reason...\t\t\tAllow remote connections",
1, SC_ALLOW, TRUE },
{ "begin", "site\t\t\tStart newly-added site",
1, SC_BEGIN, FALSE },
{ "cancel", "id\t\t\tCancel message locally",
1, SC_CANCEL, FALSE },
{ "changegroup", "group rest\tChange mode of group",
2, SC_CHANGEGROUP, FALSE },
{ "checkfile", "\t\t\tCheck syntax of newsfeeds file",
0, SC_CHECKFILE, FALSE },
{ "drop", "site\t\t\tStop feeding site",
1, SC_DROP, FALSE },
{ "flush", "site\t\t\tFlush feed for site*",
1, SC_FLUSH, FALSE },
{ "flushlogs", "\t\t\tFlush log files",
0, SC_FLUSHLOGS, FALSE },
{ "go", "reason...\t\t\tRestart after pause or throttle",
1, SC_GO, TRUE },
{ "hangup", "channel\t\tHangup specified incoming channel",
1, SC_HANGUP, FALSE },
{ "mode", "\t\t\t\tPrint operating mode",
0, SC_MODE, FALSE },
{ "name", "nnn\t\t\tPrint name of specified channel*",
1, SC_NAME, FALSE },
{ "newgroup", "group rest creator\tCreate new group",
3, SC_NEWGROUP, FALSE },
{ "param", "letter value\t\tChange command-line parameters",
2, SC_PARAM, FALSE },
{ "pause", "reason...\t\tShort-term pause in accepting articles",
1, SC_PAUSE, TRUE },
{ "readers", "flag text...\t\tEnable or disable newsreading",
2, SC_READERS, TRUE },
{ "refile", "path group\t\tRefile an article",
2, SC_REFILE, FALSE },
{ "reject", "reason...\t\t\tReject remote connections",
1, SC_REJECT, TRUE },
{ "reload", "what reason...\t\tRe-read config files*",
2, SC_RELOAD, TRUE },
{ "renumber", "group\t\tRenumber the active file*",
1, SC_RENUMBER, FALSE },
{ "reserve", "reason...\t\tReserve the next pause or throttle",
1, SC_RESERVE, TRUE },
{ "rmgroup", "group\t\t\tRemove named group",
1, SC_RMGROUP, FALSE },
{ "send", "feed text...\t\tSend text to exploder feed",
2, SC_SEND, TRUE },
{ "shutdown", "reason...\t\tShut down server",
1, SC_SHUTDOWN, TRUE },
{ "kill", "signal site\t\tSend signal to site's process",
2, SC_SIGNAL, FALSE },
{ "throttle", "reason...\t\tStop accepting articles",
1, SC_THROTTLE, TRUE },
{ "trace", "innd|#|nnrpd flag\tTurn tracing on or off",
2, SC_TRACE, FALSE },
{ "xabort", "text...\t\tAbort the server",
1, SC_XABORT, TRUE },
{ "xexec", "path\t\t\tExec new server",
1, SC_XEXEC, FALSE }
};
/*
** Print a help summary.
*/
STATIC NORETURN
Help(p)
char *p;
{
register COMMAND *cp;
if (p == NULL) {
(void)printf("Command summary:\n");
for (cp = Commands; cp < ENDOF(Commands); cp++)
(void)printf(" %s %s\n", cp->Command, cp->Text);
(void)printf("* Empty string means all sites/groups/etc.\n");
(void)printf("... All trailing words are glued together.\n");
exit(0);
}
for (cp = Commands; cp < ENDOF(Commands); cp++)
if (EQ(p, cp->Command)) {
(void)printf("Command usage:\n");
(void)printf(" %s %s\n", cp->Command, cp->Text);
exit(0);
}
(void)printf("No such command.\n");
exit(0);
}
/*
** Print a command-usage message and exit.
*/
STATIC NORETURN
WrongArgs(cp)
COMMAND *cp;
{
(void)printf("Wrong number of arguments -- usage:\n");
(void)printf(" %s %s\n", cp->Command, cp->Text);
exit(1);
}
/*
** Print an error message and exit.
*/
STATIC NORETURN
Failed(p)
char *p;
{
if (ICCfailure)
(void)fprintf(stderr, "Can't %s (%s failure) %s.\n",
p, ICCfailure, strerror(errno));
else
(void)fprintf(stderr, "Can't %s, %s.\n", p, strerror(errno));
(void)ICCclose();
exit(1);
}
/*
** Print an error reporting incorrect usage.
*/
STATIC NORETURN
Usage(what)
char *what;
{
(void)fprintf(stderr, "Usage error (%s) -- try -h for help.\n", what);
exit(1);
}
int
main(ac, av)
int ac;
char *av[];
{
static char Y[] = "y";
static char EMPTY[] = "";
register COMMAND *cp;
register char *p;
register int i;
BOOL Silent;
BOOL NeedHelp;
char *reply;
char *new;
int length;
char *nv[4];
struct stat Sb;
char buff[SMBUF];
/* Set defaults. */
Silent = FALSE;
NeedHelp = FALSE;
ICCsettimeout(CTLINND_TIMEOUT);
/* Parse JCL. */
while ((i = getopt(ac, av, "hst:")) != EOF)
switch (i) {
default:
Usage("bad flags");
/* NOTREACHED */
case 'h': /* Get help */
NeedHelp = TRUE;
break;
case 's': /* Silent -- no output */
Silent = TRUE;
break;
case 't': /* Time to wait for reply */
ICCsettimeout(atoi(optarg));
break;
}
ac -= optind;
av += optind;
if (NeedHelp)
Help(av[0]);
if (ac == 0)
Usage("missing command");
/* Look up the command word and move to the arguments. */
if (EQ(av[0], "help"))
Help(av[1]);
for (cp = Commands; cp < ENDOF(Commands); cp++)
if (EQ(av[0], cp->Command))
break;
if (cp == ENDOF(Commands))
Usage("unknown command");
ac--;
av++;
/* Check argument count. */
if (cp->Letter == SC_NEWGROUP) {
/* Newgroup command has defaults. */
switch (ac) {
default:
WrongArgs(cp);
/* NOTREACHED */
case 1:
nv[0] = av[0];
nv[1] = Y;
nv[2] = EMPTY;
nv[3] = NULL;
av = nv;
break;
case 2:
nv[0] = av[0];
nv[1] = av[1];
nv[2] = EMPTY;
nv[3] = NULL;
av = nv;
break;
case 3:
break;
}
switch (av[1][0]) {
default:
Usage("Bad group mode");
/* NOTREACHED */
case NF_FLAG_ALIAS:
case NF_FLAG_EXCLUDED:
case NF_FLAG_MODERATED:
case NF_FLAG_OK:
case NF_FLAG_NOLOCAL:
case NF_FLAG_IGNORE:
break;
}
ac = 3;
}
else if (ac > cp->argc && cp->Glue) {
/* Glue any extra words together. */
for (length = 0, i = cp->argc - 1; (p = av[i++]) != NULL; )
length += strlen(p) + 1;
for (new = p = NEW(char, length), i = cp->argc - 1; av[i]; i++) {
if (i >= cp->argc)
*p++ = ' ';
p += strlen(strcpy(p, av[i]));
}
av[cp->argc - 1] = new;
av[cp->argc] = NULL;
}
else if (ac != cp->argc)
/* All other commands must have the right number of arguments. */
WrongArgs(cp);
/* Make sure there are no separators in the parameters. */
for (i = 0; (p = av[i++]) != NULL; )
if (strchr(p, SC_SEP) != NULL) {
(void)fprintf(stderr, "Illegal character '\\%03o' in \"%s\"\n",
SC_SEP, p);
exit(1);
}
/* Do the real work. */
if (ICCopen() < 0)
Failed("setup communication");
i = ICCcommand(cp->Letter, av, &reply);
if (i < 0) {
i = errno;
if (stat(_PATH_SERVERPID, &Sb) < 0)
(void)fprintf(stderr, "No innd.pid file; did server die?\n");
(void)sprintf(buff, "send \"%s\" command", cp->Command);
errno = i;
Failed(buff);
}
if (reply) {
/* Skip "<exitcode><space>" part of reply. */
for (p = reply; *p && CTYPE(isdigit, *p); p++)
continue;
while (*p && ISWHITE(*p))
p++;
if (i != 0)
(void)fprintf(stderr, "%s\n", p);
else if (!Silent)
(void)printf("%s\n", p);
}
if (ICCclose() < 0)
Failed("end communication");
exit(i);
/* NOTREACHED */
}